package com.javasea.log4j2.util;

import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 基于Jackson的json转换工具类
 *
 * @author: 龙小南
 * @Date: 2023/2/20 17:09
 * @Version 1.0[当前版本号]
 * @version: 1.0      2023/2/20 17:09      龙小南      新建类[说明]
 * @version: 1.1      2023-03-03 15:58     xiaodc     调整
 */

public class JacksonUtils {
    protected static Logger logger = LoggerFactory.getLogger(JacksonUtils.class);
    private static ObjectMapper mapper = getMapper();

    private JacksonUtils() {
        throw new IllegalStateException("Utility class");
    }

    public static synchronized ObjectMapper getMapper() {
        ObjectMapper tmpMapper = new ObjectMapper();
        tmpMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
        tmpMapper.setSerializationInclusion(Include.NON_NULL);
        tmpMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        tmpMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);

        return tmpMapper;
    }


    public static ObjectMapper getInstance() {
        return mapper;
    }


    /**
     * 转换为 JSON 字符串
     *
     * @param obj
     * @return
     * @throws Exception
     */
    public static String toJson(Object obj) {
        try {
            return mapper.writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            logger.error("json转换发生异常: {}", e.getMessage());
        }

        return "";
    }


    /**
     * 转换为 JSON 字符串，忽略空值（空值也会转为json）
     *
     * @param obj
     * @return
     * @throws JsonProcessingException
     */
    public static String toJsonIgnoreNull(Object obj) throws JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();
        return mapper.writeValueAsString(obj);
    }


    /**
     * 转换为 JavaBean
     *
     * @param jsonString
     * @param clazz
     * @return
     * @throws JsonProcessingException
     */
    public static <T> T toPojo(String jsonString, Class<T> clazz) throws JsonProcessingException {
        return mapper.readValue(jsonString, clazz);
    }


    /**
     * 将 Map 转换为 JavaBean
     *
     * @param map
     * @param clazz
     * @return
     */
    public static <T> T toPojo(Map<?, ?> map, Class<T> clazz) {
        return mapper.convertValue(map, clazz);
    }

    /**
     * 将 JSON 对象转换为 JavaBean
     *
     * @param obj
     * @param clazz
     * @return
     * @throws JsonProcessingException
     */
    public static <T> T toPojo(Object obj, Class<T> clazz) throws JsonProcessingException {
        return toPojo((Optional.ofNullable(obj).orElse("")).toString(), clazz);
    }


    /**
     * 转为JsonNode
     *
     * @param jsonString
     * @return
     */
    public static JsonNode toJsonNode(String jsonString) {
        JsonNode jsonNode = null;
        try {
            jsonNode = mapper.readTree(jsonString);
        } catch (IOException e) {
            logger.error("转为JsonNull异常：{}", e.getMessage());
        }
        return jsonNode;
    }


    /**
     * 字符串转换为 Map<String, Object>
     *
     * @param jsonString
     * @return
     * @throws JsonProcessingException
     */
    @SuppressWarnings("unchecked")
    public static Map<String, Object> toMap(String jsonString) throws JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();
        return mapper.readValue(jsonString, Map.class);
    }


    /**
     * @param <T>
     * @param jsonStr
     * @param t
     * @return
     * @throws JsonProcessingException
     */
    public static <T> List<T> toList(String jsonStr, Class<T> t) throws JsonProcessingException {
        if (jsonStr != null && jsonStr.trim().length() > 0) {
            return Collections.emptyList();
        }

        List<T> list = null;
        list = mapper.readValue(jsonStr, mapper.getTypeFactory().constructParametricType(List.class, t));

        return list;
    }


    /**
     * 将 Map 转换为 JSON
     *
     * @param map
     * @return
     */
    public static String toJson(Map<?, ?> map) {
        try {
            return mapper.writeValueAsString(map);
        } catch (JsonProcessingException e) {
            logger.error("Map转换为Json报错：{}", e.getMessage());
        }

        return "";
    }


    /**
     * 将 JSON 对象转换为 MAP
     *
     * @param obj
     * @return
     */
    @SuppressWarnings("unchecked")
    public static Map<String, Object> toMap(Object obj) {
        Map<String, Object> map = new HashMap<>();
        try {
            map = mapper.readValue(mapper.writeValueAsString(obj), Map.class);
        } catch (Exception e) {
            logger.error("对象转map异常：{}", e.getMessage());
        }

        return map;
    }


    /**
     * 将 map 转换为 obj
     *
     * @param map
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T toObj(Map<?, ?> map, Class<T> clazz) {
        T dto = null;
        try {
            dto = mapper.readValue(mapper.writeValueAsString(map), clazz);
        } catch (Exception e) {
            logger.error("map转对象异常：{}", e.getMessage());
        }
        return dto;
    }

}
